<template>
  <div class="upload_file_container">
    <el-upload
      action=""
      :http-request="fileUploadRequest"
      :before-remove="beforeRemove"
      :before-upload="beforeFileUpload"
      :on-error="handleError"
      :on-change="handleChange"
      :on-progress="handleProgress"
      :file-list="fileList"
      :show-file-list="showFileList"
      multiple
      :limit="limits"
      class="upload-demo"
      :disabled="edit"
    >
      <el-button
        v-if="!edit"
        :loading="fileUploadLoading"
        :size="buttonStyle.size"
        :type="buttonStyle.type"
        :icon="buttonStyle.icon"
        :disabled="edit"
      >
        <!-- 作用域插槽, 用于自定义按钮内容 -->
        <slot name="text" />
      </el-button>
    </el-upload>
    <!-- 文件列表  el-icon-loading-->
    <ul v-if="showFileList && fileLists.length >= 1" class="file_list">
      <li v-for="(fileItem, key) in fileLists" :key="key">
        <span
          v-if="fileUploadLoading && fileItem.status === 'uploading' || fileItem.status === 'ready'"
          class="el-icon-loading"
        />
        <span
          v-else
          class="el-icon-document"
        />
        <span class="file_list_name">{{ fileItem.name }}</span>
        <el-button
          v-if="fileItem.status === 'success'"
          class="file_list_button"
          type="text"
          icon="el-icon-circle-close"
          @click="deleteFile(fileItem)"
        />
      </li>
    </ul>
  </div>
</template>

<script>
import {
  fileUpload,
  deleteFileSystem
} from '@/api/file-upload/fileUpload'

export default {
  props: {
    irbUpload: { type: Boolean, default: false },
    // 父组件传入的 tag、用于父组件分辨数据
    refTag: { type: [Number, String], default: null },
    flagTag: { type: String, default: null },
    // 是否显示文件列表
    showFileList: { type: Boolean, default: true },
    drag: { type: Boolean, default: false },
    // 样式配置
    buttonStyle: { type: Object, default: () => {
        return {
          type: 'primary',
          size: 'small',
          icon: '',
          text: '点击上传'
        }
      } },
    // 是否编辑
    edit: { type: Boolean, default: false },
    // 限制文件个数
    limits: { type: Number, default: 1000 }
  },
  data() {
    return {
      // 可操作性的文件列表
      fileLists: [],
      // 获取配置的 文件上传路径，暂时不要管
      backAction: sessionStorage.getItem('FILE_UPLOAD_URL'),
      // 默认文件列表
      fileList: [],
      // 文件正在上传加载遮罩层
      fileUploadLoading: false,
      // 加载成功停止的定时器
      timeStop: 0,
      // 文件id
      filesId: []
    }
  },
  methods: {
    // 清空文件列表 --> 由父组件调用
    emptyFileList() {
      // 清空
      this.fileList = [];
      this.fileLists = [];
    },
    // 删除文件，只是清除数组，未发送请求
    deleteFile(fileItem) {
      console.log(fileItem);
      const that = this;
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }).then(() => {
        deleteFileSystem(fileItem.id).then(res => {
          if (res.data) {
            this.$message({ showClose: true, message: res.msg, type: 'success' });
          } else {
            this.$message({ showClose: true, message: res.msg, type: 'error' });
          }
        })
        for (let i = 0; i < that.fileLists.length; i++) {
          if (that.fileLists[i].uid === fileItem.uid) {
            // 先告诉父组件我删除了哪个文件
            that.$emit('file-delete-succeed', that.fileLists[i].response);
            that.fileLists.splice(i, 1);
          }
        }
        // 对回显列表进行操作
        if (that.fileLists.length) {
          for (let i = 0; i < that.fileLists.length; i++) {
            if (that.fileLists[i].id === fileItem.id) {
              that.deleteFilesByFileId(that.fileLists[i].id);
              that.fileLists.splice(i, 1);
            }
          }
        }
        that.$set(that, 'fileList', that.fileLists);
      })
    },
    // 异步删除文件
    async deleteFilesByFileId(fileId) {
      await deleteFileSystem(fileId).then(response => {
        const { code, msg } = response;
        if (code === 200) {
          this.msgSuccess(msg);
        }
      })
    },
    // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    handleChange(file, fileList) {
      this.fileLists = fileList;
    },
    // 定义最大传入文件
    beforeFileUpload(file) {
      // const isLt2M = file.size / 1024 / 1024 < 200;
      // if (!isLt2M) {
      //   this.$message({ showClose: true, message: '文件大小不能超过 100MB！', type: 'error' });
      //   // 如果上传文件过大，就删除文件
      //   this.publicMethodForDeletingFiles(file);
      // }
      return true
    },
    // 覆盖原本上传事件
    fileUploadRequest(file) {
      this.fileUploadLoading = true;
      const that = this;
      if (that.funding) {
        // 调用文件上传方法
        fileUpload(file).then(response => {
          // 调用公共上传方法
          this.publicRequest(response, callBack => {
            // 如果返回为 error
            if (callBack === 'error') {
              // 清除遮罩层
              this.fileUploadLoading = false;
              return
            }
            file.onSuccess();
            // 如果父组件传入了 tag，就设置tag
            if (this.refTag !== null) {
              response.data.tag = this.refTag;
            }
            if (this.flagTag !== null) {
              response.data.flagTag = this.flagTag;
            }
            // 清除遮罩层
            this.fileUploadLoading = false;
            // 将返回的数据添加到 fileLists
            this.fileLists.forEach(element => {
              if (element.name === response.data.original) {
                element.response = response.data;
                element.id = response.data.id;
              }
            })
            // 文件列表添加文件id
            // this.$set(this.fileLists[this.fileLists.length - 1], 'id', response.data.id);
            // 发送文件已上传成功事件给父组件
            this.$emit('file-upload-succeed', true);
            this.$emit('file-data', response.data);
            this.$emit('fileLists', that.fileLists);
            this.fileUploadLoading = false;
          })
        })
      } else {
        // 调用文件上传方法
        fileUpload(file).then(response => {
          // 调用公共上传方法
          this.publicRequest(response, callBack => {
            // 如果返回为 error
            if (callBack === 'error') {
              // 清除遮罩层
              this.fileUploadLoading = false;
              return
            }
            file.onSuccess();
            // 如果父组件传入了 tag，就设置tag
            if (this.refTag !== null) {
              response.data.tag = this.refTag;
            }
            if (this.flagTag !== null) {
              response.data.flagTag = this.flagTag;
            }
            // 将返回的数据添加到 fileLists
            this.fileLists.forEach(element => {
              if (element.name === response.data.original) {
                element.response = response.data;
                element.id = response.data.id;
              }
            })
            // 如果有 irb 说明需要上传文件给伦理系统
            if (this.irbUpload) {
              response.data.file = file;
            }
            // 文件列表添加文件id
            // this.$set(this.fileLists[this.fileLists.length - 1], 'id', response.data.id);
            // 发送文件已上传成功事件给父组件
            this.$emit('file-upload-succeed', true);
            this.$emit('file-data', response.data);
            this.$emit('fileLists', that.fileLists);
            // 清除遮罩层
            this.fileUploadLoading = false;
          })
        })
      }
      // this.fileUploadLoading = false;
    },
    // 文件正在上传时的钩子
    handleProgress() {
      this.fileUploadLoading = true;
      this.$emit('file-upload-succeed', false);
    },
    // 文件列表移除文件时的钩子
    beforeRemove() {
      // TODO 直接可忽略, 涉及到需求再优化
      return true
    },
    // 文件上传失败调用钩子
    handleError(err) {
      this.$message({ showClose: true, message: '文件上传失败', type: err });
    },
    // 返回值处理公共方法
    publicRequest(response, callBack) {
      if (response.code !== 200) {
        this.$message({ showClose: true, message: '文件上传失败', type: 'error' });
        callBack && callBack('error')
        return false
      } else {
        this.$message({ showClose: true, message: '文件上传成功', type: 'success' });
        callBack && callBack('success')
        return false
      }
    },
    // 文件上传公共方法
    publicMethodForDeletingFiles(fileItem, callback) {
      for (let i = 0; i < this.fileLists.length; i++) {
        if (this.fileLists[i].uid === fileItem.uid) {
          this.fileLists.splice(i, 1);
        }
      }
      callback && callback('success');
    },
  }
}
</script>

<style>
.upload_file_container {
  display: inline-block;
}
.file_list {
  padding: 0;
  margin-top: 10px;
  list-style: none;
}
.file_list li {
  position: relative;
  display: flex;
  align-items: center;
  margin: 10px;
  font-size: 14px;
  height: 25px;
  color: #666666;
}
.file_list li:hover{
  background: #F5F7FA;
  cursor: pointer;
  color: #00afff;
  transition: 1s;
}
.file_list_name {
  margin-left: 20px;
}
.file_list_button {
  float: right;
}
.file_list_button:hover{
  font-size: 18px;
}
</style>

